home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 130_01 / yaccrl.c < prev    next >
Text File  |  1985-03-09  |  11KB  |  472 lines

  1. /* CCRL - BDS-C CRL file generator
  2. */
  3.  
  4. #include <bdscio.h>
  5.  
  6. #define DIRSTART        0x0     /*CRL directory*/
  7. #define DIREND          0x1ff   /*dir. stops here*/
  8. #define FNCSTART        0x205   /*fnc.'s can start*/
  9. #define TPAHBRLC        0x1     /*hi byte of tpa add*/
  10. #define TPA        0x100    /* tpa itself */
  11.  
  12. #define JUMPINSTR       0xc3    /*jump instr. op code*/
  13. #define MASK7           0x7f    /*seven bit mask*/
  14. #define NULENTRY        0x80    /*null function*/
  15.  
  16. #define CR              0xd     /*carriage return*/
  17. #define LF              0xa     /*line feed*/
  18.  
  19. #define EXTERN        'e'    /* rlc.type for j.t. */
  20. #define INTOFF        'i'    /* rlc.type for internal offset */
  21. /*
  22. **    The following defines may require changing for other
  23. **    assemblers, or for very large functions
  24. **    Specifically, for CP/M's ASM, the first 2 defines should be:
  25. **    #define LIST_TYPE "PRN"        and
  26. **    #define LIST_COL 1
  27. */
  28. #define LIST_TYPE    "LST"    /*file type of listing*/
  29. #define LIST_COL    5    /*1st column of address field in listing*/
  30. #define LIST_FIRST    14    /*1st col of source code*/
  31. #define MAXLINE        135    /*max input line from LST file*/
  32. #define MXFNSIZE        4096    /*max function size*/
  33. #define MXRELOCS        640     /*max no. reloc. symbls*/
  34. #define MXSYMSIZE    4096    /*max size of all external symbols*/
  35. #define FILESTRLEN    20    /*max length of one external symbol*/
  36.  
  37. char  filestr[FILESTRLEN+1];    /*where file/external names are kept*/
  38. char  function[MXFNSIZE];    /*object code*/
  39. char  symbols[MXSYMSIZE];    /*external symbol strings*/
  40. char  *s, *fn, *symp;
  41. char  fncbuf[BUFSIZ], extbuf[BUFSIZ], outbuf[BUFSIZ];
  42. char  rlctype;
  43. int   fncfd, extfd, outfd;
  44. int   addr, fsize, size, fend, outbytes;
  45. int   fip, rip, ripjt, sip, rlcoffset;
  46. int   i, j, k, ip, c, cp, pflag;
  47. struct {
  48.     int val;
  49.     char type;
  50.     } rlc[MXRELOCS];
  51.  
  52. main(argc, argv)
  53. int argc;
  54. char **argv;
  55. {
  56.     printf("CCRL Ver. 2.0\n");
  57.     pflag = FALSE;
  58.     if (argc < 2)
  59.         {
  60.         printf("usage: CCRL filename [-p]\n");
  61.         exit();
  62.         }
  63.     s = *++argv; argc -= 2;
  64.     if ((fncfd = fopen((fn = filename(s, "COM")), fncbuf)) <= 0)
  65.         {
  66.         printf("Cannot open %s\n",fn);
  67.         exit();
  68.         }
  69.     if ((extfd = fopen((fn = filename(s, LIST_TYPE)), extbuf)) <= 0)
  70.         {
  71.         printf("Cannot open %s\n",fn);
  72.         exit();
  73.         }
  74.     if ((outfd = fcreat((fn = filename(s, "CRL")), outbuf)) <= 0)
  75.         {
  76.         printf("Cannot create %s\n",fn);
  77.         exit();
  78.         }
  79.     else
  80.         printf("Creating %s\n",fn);
  81.     while (argc-- > 0)
  82.         {
  83.         s = *++argv;
  84.         if (strcmp(s, "-P") == EQUAL) pflag = TRUE;
  85.         }
  86.     if (pflag) printf("Listing will be shown\n");
  87. /*
  88. **    Initialize and read first function name in .LST file
  89. */
  90.     outbytes = -1;
  91.     addr = FNCSTART;
  92.     fn = funcname(extbuf);
  93.     if (fn == NULL)
  94.         {
  95.          printf("Error: no function name in .%s file\n", LIST_TYPE);
  96.          exit();
  97.         }
  98.     fputs(fn, outbuf);    /* send fn name to output buffer */
  99.     outbytes += strlen(fn);    /* update count of output buffer */
  100.     putw(addr, outbuf);    /* send its start address */
  101.     outbytes += 2;
  102.     putc(NULENTRY, outbuf);    /* send end of directory */
  103.     ++outbytes;
  104. /*
  105. **    Read function length & total length
  106. */
  107.     if (outbytes+2 > DIREND)
  108.         /* This is only possible when more than 1
  109.            function can be created per CRL file! */
  110.         { printf("Error: directory overflow\n");
  111.           exit();
  112.         }
  113. /*
  114. **    Now read external function names
  115. */
  116.     ip = 0;         /* count of external functions */
  117.     symp = symbols;
  118.     while ( *(fn = extname(extbuf)) != NUL)
  119.         {
  120.         strcpy(symp, fn);    /* store for later output */
  121.         symp += strlen(fn) + 1;
  122.         ip++;
  123.         }
  124.     *symp++ == NUL;        /* null byte ends it */
  125.     sip = (symp - symbols) - ip;    /* length for output format */
  126.     if(ip > 0)
  127.         {
  128.         if(3*ip >= 0xff) /* where did this number come from? */
  129.             {
  130.             printf("Sorry, to many external functions\n");
  131.             exit();
  132.             }
  133. /*
  134. **    set up JMP XXXX to hop over external jumps
  135. **    followed by the external JMP's themselves
  136. */
  137.         printf("Number of external jumps is %d\n", ip + 1);
  138.  
  139.         function[0] = JUMPINSTR;
  140.         function[1] = 3*(ip + 1);
  141.         function[2] = TPAHBRLC;
  142.         fip = 3;
  143.         for (j = 1; j <= ip; j++)
  144.             {
  145.             function[fip++] = JUMPINSTR;
  146.             function[fip++] = 0;    /* these get filled in by */
  147.             function[fip++] = 0;    /* the linker */
  148.             }
  149.         rlcoffset = 3*(ip + 1);
  150.         rlc[0].val = 1;    /* re-locate jump over jump table */
  151.         rlc[0].type = EXTERN;
  152.         rip = 1;    /* this is first relocation parameter */
  153.         }
  154.     else            /* no external calls */
  155.         {
  156.         fip = 0;
  157.         rlcoffset = 0;
  158.         rip = 0;
  159.         }
  160.     ripjt = fip;    /* part of final count */
  161. /*
  162. **    Read the relocation addresses from the .LST(.PRN) file
  163. */
  164.     do
  165.         {
  166.         if ((c = readhex(extbuf, &rlctype)) >= 0)
  167.             {
  168.             rlc[rip].type = rlctype;
  169.             rlc[rip++].val = rlcoffset + c - TPA;
  170.             }
  171.         if(rip > MXRELOCS)
  172.             {
  173.             printf("Sorry, too many reloc. parameters\n");
  174.             exit();
  175.             }
  176.         }  while (c >= 0);
  177.     printf("Number of relocations is %d\n",rip);
  178. /*
  179. **    Now read fsize bytes of object code from the .COM file
  180. */
  181.     fsize = fend - TPA;    /* this should be end address */
  182.     if (fsize + rlcoffset > MXFNSIZE)
  183.         {
  184.         printf("Sorry, function buffer size exceeded\n");
  185.         exit();
  186.         }
  187.     printf("Object code length expected is %d (%xH)\n",
  188.                         fsize, fsize);
  189.     for (j = 0; j < fsize; j++)
  190.         {
  191.         if ((c = getc(fncbuf)) == ERROR)
  192.             {
  193.             printf("Error: EOF encountered before \
  194. fsize bytes read\n");
  195.             exit();
  196.             }
  197.         function[fip++] = c;
  198.         }
  199.  
  200. /*
  201. **    Now reloc to 0 from beginning of TPA (0 or 4300)
  202. */
  203.     if (rip > 0)
  204.         {
  205. /*
  206. **        printf("Relocating jump table by %04xH\n", TPAHBRLC << 8);
  207. **        printf("Relocating local references by %04xH\n",
  208. **                (TPAHBRLC << 8) - rlcoffset);
  209. */
  210.         for (j=0; j < rip; j++)
  211.             {
  212.             if (pflag)
  213.                 printf("rlc: %4x %02x %02x %02x",
  214.                     rlc[j].val,
  215.                     function[rlc[j].val - 1],
  216.                     function[rlc[j].val],
  217.                     function[rlc[j].val + 1]);
  218.  
  219.             if (rlc[j].type == EXTERN)
  220.                 function[rlc[j].val + 1] -= TPAHBRLC;
  221.             else    {
  222.                 function[rlc[j].val] += rlcoffset;
  223.                 function[rlc[j].val + 1] -= TPAHBRLC;
  224.                 if (function[rlc[j].val] < rlcoffset)
  225.                     ++function[rlc[j].val + 1];
  226.                 }
  227.             if (pflag)
  228.                 printf(" --> %02x %02x %02x %c\n",
  229.                     function[rlc[j].val - 1],
  230.                     function[rlc[j].val],
  231.                     function[rlc[j].val + 1],
  232.                     rlc[j].type);
  233.             }
  234.         }
  235. /*
  236. **    Send pointer to next free space to output
  237. **    Finish up directory portion
  238. */
  239.     if (pflag) printf("rip: %d, ripjt: %d, sip: %d, fsize: %d\n",
  240.                rip * 2, ripjt,    sip,    fsize);
  241.     fend = 2 * rip + 2 + ripjt + sip + fsize + 2 + addr;
  242.     putw(fend, outbuf);    /* send next free space to dir. */
  243.     outbytes += 2;
  244.     if (pflag) printf("Directory size: %d\n", outbytes);
  245.  
  246.     while (outbytes < (addr - 1))    /* null fill directory */
  247.         { putc(0,outbuf);
  248.           ++outbytes;
  249.         }
  250. /*
  251. **    Send symbols to output file
  252. */
  253.     symp = symbols;
  254.     for (i=0; i < ip; i++)
  255.         while (*symp)
  256.             {
  257.             putc(*symp++, outbuf);
  258.             outbytes++;
  259.             }
  260.     putc(NUL, outbuf);    /* null byte ends it */
  261.     outbytes++;
  262. /*
  263. **    Send fixed up function code to output file
  264. **    First comes the length of the code to follow
  265. */
  266.     putw(fsize + ripjt * 3, outbuf);
  267.     outbytes += 2;
  268.     for (j=0; j < fip; j++)
  269.         {
  270.         putc(function[j], outbuf);
  271.         ++outbytes;
  272.         }
  273. /*
  274. **    This outputs the relocation parameters
  275. **    First comes the amount of them
  276. */
  277.     putw(rip, outbuf);
  278.     outbytes += 2;
  279.     for (i=0; i < rip; i++)
  280.         {
  281.         putw(rlc[i].val, outbuf);
  282.         outbytes += 2;
  283.         }
  284.  
  285.     printf("outbytes = 0x%04x, fend = 0x%04x\n", outbytes, fend);
  286.     if(outbytes >= fend)    /* somebody goofed */
  287.         {
  288.         printf("Error: outbytes >= fend\n");
  289.         exit();
  290.         }
  291.     else if ((outbytes + 1) == fend)
  292.         printf("Everything seems hunky-dory.\n");
  293.     else    printf("Something's wrong here...\
  294. actual end differs from expected.\n");
  295. /*
  296. **    Done, close up and leave
  297. */
  298.     fabort(fncfd);
  299.     fabort(extfd);
  300.     fflush(outbuf);
  301.     fclose(outbuf);
  302.     printf("\nCRL file created.\n");
  303. }
  304.  
  305. /*
  306. **    Stick extension (type) to end of name
  307. **    Ignore any existing extension
  308. **    Returns new name in filestr
  309. */
  310. char *filename(flnmptr, flnmend)
  311. char *flnmptr, *flnmend;
  312. {
  313.     int i, havedot;
  314.  
  315.     havedot = 0;
  316.     i = -1;
  317.     while ((filestr[++i] = *flnmptr++)  !=  NUL)
  318.         havedot |= (filestr[i] == '.');
  319.     if (!havedot)